<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="../../index.css">
    <script src="https://unpkg.com/canvaskit-wasm@latest/bin/canvaskit.js"></script>
    <script src="../dist/iife/spine-canvaskit.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body class="p-4 flex flex-col items-center">
    <h1>IK Following</h1>
    <p class="mb-4">Drag anywhere</p>
    <canvas id=foo style="margin: 0 auto; width: 600px; height: 400px;"></canvas>
</body>

<script type="module">
    async function readFile(path) {
        const response = await fetch(path);
        if (!response.ok) throw new Error("Could not load file " + path);
        return await response.arrayBuffer();
    }

    const canvasElement = document.querySelector("#foo");
    const dpr = window.devicePixelRatio || 1;
    canvasElement.width = canvasElement.clientWidth * dpr;
    canvasElement.height = canvasElement.clientHeight * dpr;

    const ck = await CanvasKitInit();
    const surface = ck.MakeCanvasSurface('foo');
    surface.getCanvas().scale(dpr, dpr);

    const atlas = await spine.loadTextureAtlas(ck, "/assets/celestial-circus.atlas", readFile);
    const skeletonData = await spine.loadSkeletonData("/assets/celestial-circus-pro.json", atlas, readFile);
    const drawable = new spine.SkeletonDrawable(skeletonData);
    drawable.skeleton.scaleX = drawable.skeleton.scaleY = 0.15;
    drawable.skeleton.x = 300;
    drawable.skeleton.y = 300;

    // Set the blink animation on track 0
    drawable.animationState.setAnimation(0, "eyeblink-long", true);

    // Set up touch and mouse listeners on the canvas element
    // and set the touch/mouse coordinate on the aim bone
    let mouseDown = false;
    let lastX = -1, lastY = -1;
    canvasElement.addEventListener("touchmove", (ev) => drag(ev.changedTouches[0].clientX, ev.changedTouches[0].clientY));
    canvasElement.addEventListener("mousedown", (ev) => {
        mouseDown = true;
        drag(ev.clientX, ev.clientY);
    });
    canvasElement.addEventListener("mouseup", () => {
        mouseDown = false;
        lastX = -1; lastY = -1;
    })
    canvasElement.addEventListener("mousemove", (ev) => {
        if (mouseDown) drag(ev.clientX, ev.clientY);
    })

    // Move the skeleton around based on the distance between
    // the last touch/mouse location and the current touch/mouse location.
    const drag = (touchX, touchY) => {
        const clientRect = canvasElement.getBoundingClientRect();
        let x = touchX - clientRect.left;
        let y = touchY - clientRect.top;
        if (lastX == -1 && lastY == -1) {
            lastX = x;
            lastY = y;
            return;
        }

        drawable.skeleton.x += (x - lastX);
        drawable.skeleton.y += (y - lastY);
        lastX = x;
        lastY = y;
    }

    const renderer = new spine.SkeletonRenderer(ck);
    let lastTime = performance.now();

    function drawFrame(canvas) {
        canvas.clear(ck.Color(52, 52, 54, 1));

        const now = performance.now();
        const deltaTime = (now - lastTime) / 1000;
        lastTime = now;

        drawable.update(deltaTime);
        renderer.render(canvas, drawable);

        surface.requestAnimationFrame(drawFrame);
    }
    surface.requestAnimationFrame(drawFrame);
</script>

</html>